第25章 字符串与字符数组
在程序设计中,字符串是由字符组成的序列,常用于表示文本信息。在C语言中,字符串通过字符数组实现;而C++语言中,除字符数组外,还提供string类简化字符串操作。
25.1 字符数组与字符串基础概念
25.1.1 字符数组
存储字符类型的数组,可存储任意字符,不一定带结束符\0,不属于字符串。
示例:
char arr[3] = {'A','B','C'}; // 纯字符数组,无'\0',不是字符串
25.1.2 字符串
以空字符\0(ASCII值0)作为结束标记的字符序列,必须存储在字符数组中。
char str1[6] = {'H','e','l','l','o','\0'};
char str2[] = "World"; // 编译器自动末尾追加'\0'
25.2 字符数组定义与初始化
25.2.1 逐个字符初始化
手动填写每个字符,可手动添加\0转为字符串:
char c1[6] = {'C','h','i','n','a','\0'}; // 合法字符串
char c2[3] = {'a','b','c'}; // 仅字符数组,无结束符
25.2.2 字符串常量初始化
直接使用双引号字符串,编译器自动补充\0:
char s1[] = "Hello"; // 数组长度6:H e l l o \0
char s2[10] = "Hi"; // 前两字符H i,剩余全部填充'\0'
25.3 字符串输入输出
25.3.1 C语言风格(printf / scanf / puts / gets)
头文件:<stdio.h>
- printf / puts 输出
char str[] = "Hello World";
printf("%s\n", str); // %s读到'\0'停止
puts(str); // 自动换行,无需格式符
- scanf 输入:遇到空格、换行停止
char input[20];
scanf("%s", input);
- gets:读取带空格字符串,C11标准已废弃,存在缓冲区溢出安全漏洞。
25.3.2 C++ cin / cout
#include <iostream>
using namespace std;
char input[20];
cin >> input; // 空格截断
cout << input << endl;
25.3.3 cin.getline 读取整行(含空格)
char line[50];
cin.getline(line, 50); // 最多读取49字符,自动补'\0'
25.4 C字符串标准库函数(头文件<cstring>)
25.4.1 strlen 获取字符串长度
功能:统计有效字符,不包含\0
char s[] = "Hello";
int len = strlen(s); // len = 5
25.4.2 strcpy 字符串复制
将源字符串完整复制到目标数组(含\0),目标数组空间必须充足:
char dest[20];
char src[] = "Copy me";
strcpy(dest, src);
25.4.3 strcat 字符串拼接
把源字符串追加到目标末尾,覆盖原\0,末尾重新添加结束符:
char dest[20] = "Hello";
char src[] = " World";
strcat(dest, src); // dest = "Hello World"
25.4.4 strcmp 字符串比较
按ASCII码逐字符对比:
- s1 > s2:返回正数
- s1 == s2:返回0
- s1 < s2:返回负数
int res1 = strcmp("apple", "banana"); // 负数
int res2 = strcmp("hello", "hello"); // 0
25.4.5 strncmp 限定长度比较
仅对比前n个字符:
int res = strncmp("abcde", "abcfg", 3); // 前3位相等,返回0
25.5 C++ string 类(头文件<string>)
25.5.1 string 对象初始化
string s1; // 空字符串
string s2 = "Hello";
string s3(s2); // 拷贝s2
string s4(5, 'A'); // 5个'A':"AAAAA"
25.5.2 常用成员与运算符
- 长度:
s.length()/s.size() - 判断空:
s.empty() - 拼接:
+/+=
string a = "Hi", b = " C++";
string c = a + b;
a += b;
- 字符访问:
s[下标]/s.at(下标)(at会越界检查) - 直接比较:
==<>运算符重载 - 查找子串
.find(子串),未找到返回string::npos
string s = "Hello World";
size_t pos = s.find("World"); // pos = 6
- 字符串替换
.replace(起始, 长度, 新串)
25.6 char数组与string相互转换
string转C风格字符指针:.c_str()
string s = "Test";
const char* p = s.c_str();
25.7 使用注意事项
- C字符串必须以
\0结尾,库函数依赖结束符,缺失会乱码; - strcpy、strcat必须保证目标数组容量足够,否则数组越界;
- gets函数禁用,优先使用cin.getline / fgets;
- string更安全,无需手动管理缓冲区,竞赛推荐优先使用;
- getline读取前若有cin遗留换行,需清空缓冲区。